using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using FuncWorks.Xna.UI;
using FuncWorks.Xna.Input;
using FuncWorks.Xna.UI.Menu;

namespace MenuDemo {
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        List<Controller> controllers;
        MenuManager menu;

    	KeyboardState lastKeyboard;

        public Game1() {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize() {
            controllers = new List<Controller>();
            controllers.Add(new Controller(PlayerIndex.One));
            controllers.Add(new Controller(PlayerIndex.Two));
            controllers.Add(new Controller(PlayerIndex.Three));
            controllers.Add(new Controller(PlayerIndex.Four));

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent() {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            TextStyle textStyle = new TextStyle(Content.Load<SpriteFont>("SpriteFont1"), Color.White, Color.Black, 1, AnchorPoint.BottomRight);
            TextStyle textStyle2 = new TextStyle(Content.Load<SpriteFont>("SpriteFont1"), Color.Yellow, Color.Black, 1, AnchorPoint.BottomRight);
            TextStyle textStyle3 = new TextStyle(Content.Load<SpriteFont>("SpriteFont1"), Color.Gray, Color.Black, 1, AnchorPoint.BottomRight);

            menu = new MenuManager(
                new Rectangle(
                    graphics.GraphicsDevice.Viewport.TitleSafeArea.Left,
                    graphics.GraphicsDevice.Viewport.TitleSafeArea.Top,
                    graphics.GraphicsDevice.Viewport.TitleSafeArea.Width,
                    graphics.GraphicsDevice.Viewport.TitleSafeArea.Height
                    ),
                textStyle,
                textStyle2,
                textStyle3,
                2
            );

            Texture2D menu_sel = Content.Load<Texture2D>("menu_sel");
            Texture2D menu_unsel = Content.Load<Texture2D>("menu_unsel");

            menu.MenuItems.Add(new SelectItem("Item 1", BlockAlignment.Left));

        	menu.MenuItems.Add(new SelectItem("Hidden Item", BlockAlignment.Left));
        	menu.MenuItems[1].Hidden = true;

			menu.MenuItems.Add(new SelectItem("Disabled Item", BlockAlignment.Left));
        	menu.MenuItems[2].Enabled = false;

            menu.MenuItems.Add(new BooleanItem("Item 2", TextAlignment.Justified, "Yes", "No", true));
            menu.MenuItems.Add(new IntegerItem("Item 3", TextAlignment.Justified, 0, 100, 50, 10));
            menu.MenuItems.Add(new ChoiceItem("Item 4", TextAlignment.Justified, new string[] { "One", "Two", "Three" }, 0, false));
            menu.MenuItems.Add(new ImageSelectItem(BlockAlignment.Left, menu_unsel, menu_sel, null));
            menu.MenuItems.Add(new SelectItem("Item 5", BlockAlignment.Center));
            menu.MenuItems.Add(new BooleanItem("Item 6", TextAlignment.Center, "On", "Off", false));
            menu.MenuItems.Add(new IntegerItem("Item 7", TextAlignment.Center, 0, 100, 50, 10));
            menu.MenuItems.Add(new ChoiceItem("Item 8", TextAlignment.Center, new string[] { "A", "B", "C", "D", "E" }, 2, true));
            menu.MenuItems.Add(new ImageSelectItem(BlockAlignment.Center, menu_unsel, menu_sel, null));
            menu.MenuItems.Add(new SelectItem("Item 9", BlockAlignment.Right));
            menu.MenuItems.Add(new ImageSelectItem(BlockAlignment.Right, menu_unsel, menu_sel, null));
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent() {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime) {
            foreach (Controller c in controllers) {
                c.Update(gameTime);

                if (c.ButtonReleased[Buttons.Back]) { this.Exit(); }

                if (c.ButtonReleased[Buttons.DPadUp]) { menu.MoveUp(); }
                else if (c.ButtonReleased[Buttons.DPadDown]) { menu.MoveDown(); }
                else if (c.ButtonReleased[Buttons.DPadLeft]) { menu.MoveLeft(); }
                else if (c.ButtonReleased[Buttons.DPadRight]) { menu.MoveRight(); }
                else if (c.ButtonReleased[Buttons.Start]) { menu.Activate(); }
            }

        	KeyboardState keyboard = Keyboard.GetState();
			if (lastKeyboard != null)
			{
				if (lastKeyboard.IsKeyUp(Keys.Up) && keyboard.IsKeyDown(Keys.Up))
				{
					menu.MoveUp();
				}
				if (lastKeyboard.IsKeyUp(Keys.Down) && keyboard.IsKeyDown(Keys.Down))
				{
					menu.MoveDown();
				}
				if (lastKeyboard.IsKeyUp(Keys.Left) && keyboard.IsKeyDown(Keys.Left))
				{
					menu.MoveLeft();
				}
				if (lastKeyboard.IsKeyUp(Keys.Right) && keyboard.IsKeyDown(Keys.Right))
				{
					menu.MoveRight();
				}
				if (lastKeyboard.IsKeyUp(Keys.Enter) && keyboard.IsKeyDown(Keys.Enter))
				{
					menu.Activate();
				}
				if (lastKeyboard.IsKeyUp(Keys.Escape) && keyboard.IsKeyDown(Keys.Escape))
				{
					Exit();
				}
			}
        	lastKeyboard = keyboard;

        	base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime) {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            menu.Draw(spriteBatch);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
